package com.jinwei.qunguanjia.common.utils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 行转列工具类
 */
public class RowConvertColUtils {
    private static Set<Object> headerSet;
    private static Set<Object> fixedColumnSet;

    private RowConvertColUtils() {
    }

    public static class ConvertData {
        private Set<Object> headerSet;
        private Set<Object> fixedColumnSet;
        private List<List<Object>> dataList;

        public ConvertData(List<List<Object>> dataList, Set<Object> headerSet, Set<Object> fixedColumnSet) {
            this.headerSet = headerSet;
            this.fixedColumnSet = fixedColumnSet;
            this.dataList = dataList;
        }

        public Set<Object> getHeaderSet() {
            return headerSet;
        }

        public void setHeaderSet(Set<Object> headerSet) {
            this.headerSet = headerSet;
        }

        public Set<Object> getfixedColumnSet() {
            return fixedColumnSet;
        }

        public void setfixedColumnSet(Set<Object> fixedColumnSet) {
            this.fixedColumnSet = fixedColumnSet;
        }

        public List<List<Object>> getDataList() {
            return dataList;
        }

        public void setDataList(List<List<Object>> dataList) {
            this.dataList = dataList;
        }
    }

    /**
     * 行转列,返回ConvertData
     *
     * @param originalList   	要行转列的List
     * @param headerName    	要行转列的字段
     * @param fixedColumn  		固定列字段
     * @param valueFiledName 	行转列字段对应值列的字段名
     * @param needHeader    	是否返回表头
     * @param fixedColumnName   固定列字段名称数组
     * @param nullValue    		定义空值补数
     * @return ConvertData
     */
    public static synchronized ConvertData doConvertReturnObj(List originalList, String headerName, String[] fixedColumn
            , String valueFiledName, boolean needHeader,String[] fixedColumnName,String nullValue) throws Exception {
        List<List<Object>> lists = doConvert(originalList, headerName, fixedColumn, valueFiledName, needHeader,fixedColumnName,nullValue);
        return new ConvertData(lists, headerSet, fixedColumnSet);
    }

    /**
     * 行转列,返回转换后的list
     *
     * @param originalList   	要行转列的List
     * @param headerName    	要行转列的字段
     * @param fixedColumn  		固定列字段
     * @param valueFieldName 	行转列字段对应值列的字段名
     * @param needHeader    	是否返回表头
     * @param fixedColumnName   固定列字段名称数组
     * @param nullValue    		定义空值补数
     */
    public static synchronized List<List<Object>> doConvert(List originalList, String headerName, String[] fixedColumn
            , String valueFieldName, boolean needHeader,String[] fixedColumnName,String nullValue) throws Exception {
        headerSet = new LinkedHashSet<>();
        fixedColumnSet = new LinkedHashSet<>();
        //resultList:首行名称list
        List<List<Object>> resultList = new ArrayList<>();

        getHeaderFixedColumnSet(originalList, headerName, fixedColumn);
        if (needHeader) {
            List<Object> headerList = new ArrayList<>();
            //填充进header
            for(String value:fixedColumnName) {
                headerList.add(value);
            }
            headerList.addAll(headerSet);
            resultList.add(headerList);
        }
        for (Object fixedColumnItem : fixedColumnSet) {
            //colList：数据list
            List<Object> colList = new ArrayList<>();
            //名称
            for(String ColNameItem:fixedColumnItem.toString().split("\\|")) {
                colList.add(ColNameItem);
            }
            for (Object headerItem : headerSet) {
                boolean flag = true;
                for (Object originalObjectItem : originalList) {
                    Field headerField = originalObjectItem.getClass().getDeclaredField(headerName);
                    headerField.setAccessible(true);
                    Field valueField = originalObjectItem.getClass().getDeclaredField(valueFieldName);
                    valueField.setAccessible(true);
                    StringBuilder fixedColumnValue = new StringBuilder();
                    if (headerItem.equals(headerField.get(originalObjectItem))) {
                        for(String string : fixedColumn){
                            Field fixedColumnField = originalObjectItem.getClass().getDeclaredField(string);
                            fixedColumnField.setAccessible(true);
                            fixedColumnValue.append(fixedColumnField.get(originalObjectItem)).append("|");
                        }
                        fixedColumnValue = new StringBuilder(fixedColumnValue.substring(0, fixedColumnValue.length() - 1));
                        if (fixedColumnItem.toString().equals(fixedColumnValue.toString())) {
                            colList.add(valueField.get(originalObjectItem));
                            flag = false;
                            break;
                        }
                    }
                }
                if (flag) {
                    colList.add(nullValue);
                }
            }
            resultList.add(colList);
        }
        return resultList;
    }

    private static void getHeaderFixedColumnSet(List originalList, String headerName, String[] fixedColumn) throws NoSuchFieldException, IllegalAccessException {
        for (Object item : originalList) {
            Field headerField = item.getClass().getDeclaredField(headerName);
            headerField.setAccessible(true);
            headerSet.add(headerField.get(item));
            StringBuffer sBuffer = new StringBuffer();
            int len = 1;
            for(String name:fixedColumn) {
                Field fixedColumnField = item.getClass().getDeclaredField(name);
                fixedColumnField.setAccessible(true);
                sBuffer.append(fixedColumnField.get(item));
                if(len<fixedColumn.length) {
                    sBuffer.append("|");
                }
                len++;
            }
            fixedColumnSet.add(sBuffer.toString());
        }
    }
}